<?php
declare(strict_types=1);

namespace LiLei\Validation;

use Illuminate\Translation\Translator;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Translation\FileLoader;
use Illuminate\Validation\Factory;

class MyValidator
{
    public static $validator;
    // 错误信息
    public static $message = [];
    // 语言文件夹
    // "./lang/en/validation.php"，路径必须是绝对路径
    public static $path    = "";
    // 语言
    public static $lang    = "";

    public function __construct()
    {
        $this->setLang();
        $this->setPath();
    }

    /**
     * 获取路径
     *
     * @return string
     */
    public function getPath()
    {
        if (1 > strlen(self::$path)) $this->setPath();

        return self::$path;
    }// getPath() end

    /**
     * 设置路径
     *
     * @param string $path 绝对路径
     * @return mixed
     */
    public function setPath(string $path = "")
    {
        self::$path = __DIR__.'/lang';
        if (strlen($path) > 0) self::$path = $path;

        return $this;
    }// setPath() end

    /**
     * 获取语言
     *
     * @return string
     */
    public function getLang()
    {
        if (1 > strlen(self::$lang)) $this->setLang();

        return self::$lang;
    }// getLang() end

    /**
     * 设置语言
     *
     * @param string $lang 语言包路径
     * @return $this
     */
    public function setLang(string $lang = "zh-CN")
    {
        if (strlen($lang) > 0) self::$lang = $lang;

        return $this;
    }// setLane() end

    // 生成 validator 实例
    public static function generateInstance()
    {
        if (is_object(self::$validator)) return self::$validator;

        $loader          = new FileLoader(new Filesystem, self::$path);
        $translator      = new Translator($loader, self::$lang);
        self::$validator = new Factory($translator);

        return self::$validator;
    }// generateInstance() end

    /**
     * 验证过程
     *
     * @param array $data               验证数据
     * @param array $rules              验证规则
     * @param array $messages           自定义消息
     * @param array $customAttributes   自定义属性
     * @return bool
     * @throws \Exception
     */
    public function validator(array $data = [], array $rules = [], array $messages = [], array $customAttributes = [])
    {
        if (empty($rules)) throw new \Exception("验证规则不能为空");
        if (empty($data)) throw new \Exception("验证数据不能为空");
        if (is_array($customAttributes) === false) throw new \Exception("自定义属性必须是数组类型");

        if (is_array($data) && is_array($rules))
        {
            $validator     = $this->generateMake($data, $rules, $messages, $customAttributes);
            $json          = \json_encode($validator->messages(), JSON_UNESCAPED_UNICODE);
            self::$message = \json_decode($json, true);

            if ($validator->fails()) return false;

            return true;
        }

        throw new \Exception("必须为数组类型");
    }// validator() end

    /**
     * 验证实例
     *
     * @param array $data               验证数据
     * @param array $rules              验证规则
     * @param array $messages           自定义信息
     * @param array $customAttributes   自定义属性
     * @return \Illuminate\Validation\Validator
     */
    private static function generateMake(array $data, array $rules, array $messages = [], array $customAttributes = [])
    {
        return self::generateInstance()->make($data, $rules, $messages, $customAttributes);
    }// generateMake() end

    /**
     * 获取错误信息
     *
     * @param bool $format
     * @return array
     */
    public function getMessage(bool $format = true)
    {
        $messages = self::$message;
        if ($format)
        {
            $messages = [];
            foreach (self::$message as $message){
                foreach($message as $error){
                    $messages[] = $error;
                }
            }
        }
        // $format = true
        /*array(
            [0] => "账户 不能为空。",
        );*/

        // $format = false
        /*Array
        (
            [account] => Array
            (
                [0] => "大胆，不能是空的",
            )
        )*/

        return $messages;
    }// getMessage() end
}